<template>
  <el-form v-if="control" ref="controlEdit" :model="control" :rules="rules" label-width="120px">
    <el-card header="基础配置">
      <el-row :gutter="24">
        <el-col :span="12">
          <el-form-item label="标题" prop="Name">
            <el-input v-model="control.Name" :maxlength="50" placeholder="标题" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="说明" prop="Show">
            <el-input v-model="control.Show" :maxlength="50" placeholder="说明" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-card>
    <el-tabs v-model="curTab" type="border-card" style="margin-top: 10px;" @tab-click="tabChange">
      <el-tab-pane label="数据源配置" name="data">
        <el-form-item label="选择数据源" prop="FormId">
          <formInput
            v-model="control.FormId"
            placeholder="选择表单"
            :form-type="[2]"
            @change="(val) => {
              formId = val ? [val] : null
            }"
          />
        </el-form-item>
        <el-form-item label="报表类型" prop="ChartType">
          <enumItem
            v-model="control.ChartType"
            :dic-key="EnumDic.PageChartType"
            placeholder="报表类型"
            sys-head="form"
            @change="typeChange"
          />
        </el-form-item>
        <el-form-item label="维度" prop="GroupBy">
          <formColChiose
            key="GroupBy"
            v-model="control.GroupBy"
            :disabled="control.FormId == null"
            :show-mode="[0]"
            placeholder="请选择维度"
            :is-mulite="true"
            :max="max ? max.dimension : null"
            :form-id="formId"
            @change="dimensionChange"
          />
        </el-form-item>
        <el-form-item label="选择指标列" prop="Selects">
          <el-row v-for="(item, index) in control.Selects" :key="item.id" style="margin-bottom: 5px;">
            <el-col :span="4">
              <el-form-item
                :prop="'Selects.' + index + '.FuncType'"
                :rules="[{
                  required: true,
                  message: '计数方式不能为空！',
                  trigger: 'blur'
                }]"
              >
                <el-select
                  v-model="item.FuncType"
                  placeholder="计数方式"
                  @change="() => item.ver = item.ver + 1"
                >
                  <el-option label="计数" :value="1" />
                  <el-option label="去重计数" :value="5" />
                  <el-option label="取和" :value="2" />
                  <el-option label="最小值" :value="3" />
                  <el-option label="最大值" :value="4" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="11">
              <el-form-item
                :prop="'Selects.' + index + '.ColumnId'"
                :rules="[{
                  required: true,
                  message: '请选择指标列',
                  trigger: 'blur'
                }]"
              >
                <formColChiose
                  :key="'col_'+item.id"
                  v-model="item.ColumnId"
                  :label.sync="item.ColName"
                  :func-type="filterFuncType(item.FuncType)"
                  :show-mode="[0]"
                  :filter-data-type="filterDataType(item.FuncType)"
                  :ver="item.ver"
                  :table-id.sync="item.TableId"
                  placeholder="请选择指标列"
                  :form-id="formId"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item
                :prop="'Selects.' + index + '.Label'"
                :rules="[{
                  required: true,
                  message: '请输入指标名称',
                  trigger: 'blur'
                }]"
              >
                <el-input v-model="item.Label" :maxlength="10" placeholder="指标名称" />
              </el-form-item>
            </el-col>
            <el-col :span="1" style="text-align: center;">
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-delete"
                circle
                @click="drop(item, index)"
              />
            </el-col>
          </el-row>
          <el-button
            v-if="normisShow"
            :disabled="control.FormId == null || max == null"
            icon="el-icon-plus"
            @click="addSelect"
          />
        </el-form-item>
        <pageFilterEdit ref="pageFilter" :form-id="control.FormId" :disabled="control.FormId == null" :items="control.Where" />
      </el-tab-pane>
      <el-tab-pane label="控件样式" name="style">
        <el-row>
          <el-col :span="15">
            <div class="controlView">
              <chartControl
                :id="control.Id"
                :width="control.WidthRatio"
                :height="control.HeightGrid"
                :title="control.Name"
                :item="controlSet"
                :content-width="contentWidth"
              />
            </div>
          </el-col>
          <el-col :span="9" style="max-height: 600px; overflow-y: auto;padding-right:10px;">
            <div class="header">呈现样式</div>
            <el-form-item label="占用宽度" prop="WidthRatio">
              <el-select v-model="control.WidthRatio" style="width: 100%;" placeholder="占用宽度">
                <el-option label="1/6" :value="6" />
                <el-option label="1/5" :value="5" />
                <el-option label="1/4" :value="4" />
                <el-option label="1/3" :value="3" />
                <el-option label="1/2" :value="2" />
                <el-option label="2/3" :value="23" />
                <el-option label="整行" :value="1" />
              </el-select>
            </el-form-item>
            <el-form-item label="占用高度(格)" prop="HeightGrid">
              <el-input-number
                v-model="control.HeightGrid"
                :min="5"
                :max="30"
                :step="1"
                :precision="0"
                style="width: 100%;"
                placeholder="占用高度(格)"
              />
            </el-form-item>
            <el-form-item label="是否显示头部" prop="IsShowHead">
              <el-switch
                v-model="control.IsShowHead"
                @change="(val) => {
                  controlSet.IsShowHead = val
                }"
              />
            </el-form-item>
            <div class="header">标题配置</div>
            <el-form-item label="是否显示" prop="Title.Show">
              <el-switch
                v-model="control.Title.Show"
                @change="(val) => {
                  controlSet.Title.Show = val
                }"
              />
            </el-form-item>
            <el-form-item label="显示位置" prop="Title.Align">
              <enumItem
                :value="control.Title.Align"
                :dic-key="EnumDic.ChartTitleAlign"
                placeholder="显示位置"
                sys-head="form"
                @change="(val) => {
                  controlSet.Title.Align = val
                }"
              />
            </el-form-item>
            <div class="header">图例配置</div>
            <el-form-item label="是否显示" prop="Legend.Show">
              <el-switch
                v-model="control.Legend.Show"
                @change="(val) => {
                  controlSet.Legend.Show = val
                }"
              />
            </el-form-item>
            <el-form-item label="显示位置" prop="Legend.Position">
              <enumItem
                :value="control.Legend.Position"
                :dic-key="EnumDic.ChartLegendPosition"
                placeholder="显示位置"
                sys-head="form"
                @change="(val) => {
                  controlSet.Legend.Position = val
                }"
              />
            </el-form-item>
            <template v-if="control.ChartType === 2 || control.ChartType === 1 || control.ChartType === 3 || control.ChartType === 5">
              <div class="header">辅助线</div>
              <el-row v-for="(line,index) in control.MarkLine" :key="index" style=" line-height: 40px;height: 40px;">
                <el-col :span="18"> {{ line.Label }}</el-col>
                <el-col :span="6">
                  <el-button
                    type="primary"
                    size="mini"
                    icon="el-icon-edit"
                    circle
                    @click="editLine(line, index)"
                  />
                  <el-button
                    type="danger"
                    size="mini"
                    icon="el-icon-delete"
                    circle
                    @click="dropLine(index)"
                  />
                </el-col>
              </el-row>
              <el-button
                style="margin-bottom: 10px; margin-top: 10px;"
                icon="el-icon-plus"
                @click="addLine"
              />
              <div class="header">Y轴配置</div>
              <el-form-item label="最小间隔大小" prop="YAxis.MinInterval">
                <el-input-number
                  v-model="control.YAxis.MinInterval"
                  :min="0"
                  :precision="1"
                  placeholder="最小间隔大小"
                  @change="(val) => {
                    controlSet.YAxis.MinInterval = val
                  }"
                />
              </el-form-item>
              <el-form-item label="最大间隔大小" prop="YAxis.MaxInterval">
                <el-input-nbmber
                  v-model="control.YAxis.MaxInterval"
                  placeholder="最大间隔大小"
                  @change="(val) => {
                    controlSet.YAxis.MaxInterval = val
                  }"
                />
              </el-form-item>
              <el-form-item label="单位" prop="YAxis.Unit">
                <el-input
                  v-model="control.YAxis.Unit"
                  :maxlength="10"
                  placeholder="单位"
                  @change="(val) => {
                    controlSet.YAxis.Unit = val
                  }"
                />
              </el-form-item>
              <template v-if="control.ChartType === 5">
                <div class="header">X轴配置</div>
                <el-form-item label="单位" prop="XAxis.Unit">
                  <el-input
                    v-model="control.XAxis.Unit"
                    :maxlength="10"
                    placeholder="单位"
                    @change="(val) => {
                      controlSet.XAxis.Unit = val
                    }"
                  />
                </el-form-item>
              </template>
            </template>
          </el-col>
        </el-row>
      </el-tab-pane>
    </el-tabs>
    <editMarkLine :visible.sync="visible" :mark-index="markIndex" :mark="mark" :columns="columns" @save="saveMark" />
  </el-form>
</template>

<script>
import formInput from '@/customForm/components/form/formInput.vue'
import formColChiose from '@/customForm/components/form/formColChiose.vue'
import pageFilterEdit from './pageFilterEdit.vue'
import { EnumDic } from '@/customForm/config/formConfig'
import chartControl from '@/customForm/views/customPage/control/chartControl.vue'
import editMarkLine from './editMarkLine.vue'
export default {
  components: {
    formInput,
    formColChiose,
    pageFilterEdit,
    chartControl,
    editMarkLine
  },
  props: {
    contentWidth: {
      type: Number,
      default: null
    },
    source: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      EnumDic,
      control: null,
      id: 1,
      normisShow: true,
      mark: null,
      controlSet: null,
      formId: null,
      visible: false,
      columns: [],
      markIndex: null,
      chartMax: {
        0: {
          norm: 1,
          dimension: 1
        },
        2: {
          norm: () => {
            return this.control.GroupBy.length <= 1 ? 5 : 1
          },
          dimension: () => {
            return this.control.Selects.length <= 1 ? 2 : 1
          }
        },
        1: {
          norm: () => {
            return this.control.GroupBy.length <= 1 ? 5 : 1
          },
          dimension: () => {
            return this.control.Selects.length <= 1 ? 2 : 1
          }
        },
        3: {
          norm: () => {
            return this.control.GroupBy.length <= 1 ? 5 : 1
          },
          dimension: () => {
            return this.control.Selects.length <= 1 ? 2 : 1
          }
        },
        4: {
          norm: () => {
            return this.control.GroupBy.length <= 1 ? 5 : 1
          },
          dimension: () => {
            return this.control.Selects.length <= 1 ? 2 : 1
          }
        },
        5: {
          norm: 2,
          dimension: 2
        }
      },
      curTab: 'data',
      max: null,
      rules: {
        Name: [
          {
            required: true,
            message: '标题不能为空！',
            trigger: 'blur'
          }
        ],
        WidthRatio: [
          {
            required: true,
            message: '请选择占用宽度！',
            trigger: 'blur'
          }
        ],
        HeightGrid: [
          {
            required: true,
            message: '请选择占用高度！',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  watch: {
    source: {
      handler(val) {
        if (val) {
          this.resetForm()
        } else {
          this.control = null
        }
      },
      immediate: true
    }
  },
  mounted() { },
  methods: {
    dimensionChange(val, form) {
      this.checkNorm()
      if (this.control.ChartType !== 2) {
        return
      } else if (form.length > 1) {
        const t = form[1]
        this.columns = [{
          Id: t.Id,
          Name: t.Name
        }]
      } else {
        this.columns = this.Selects.map(c => {
          return {
            Id: c.ColumnId,
            Name: c.ColName
          }
        })
      }
    },
    checkNorm() {
      if (this.max == null) {
        this.normisShow = false
      } else if (this.max.norm instanceof Function) {
        this.normisShow = this.control.Selects.length < this.max.norm()
      } else {
        this.normisShow = this.control.Selects.length < this.max.norm
      }
    },
    typeChange(val) {
      this.max = this.chartMax[val]
      this.checkNorm()
    },
    filterDataType(type) {
      if (type === 1 || type === 5) {
        return []
      } else {
        return [2, 3, 6, 9]
      }
    },
    filterFuncType(type) {
      if (type === 1 || type === 5) {
        return []
      } else {
        return [0]
      }
    },
    tabChange() {
      if (this.curTab === 'style') {
        this.initControlSet()
      }
    },
    drop(item, index) {
      this.control.Selects.splice(index, 1)
      this.checkNorm()
    },
    addSelect() {
      this.control.Selects.push({
        id: this.id,
        TableId: null,
        ColumnId: null,
        Label: null,
        FuncType: 1,
        Color: null
      })
      this.id = this.id + 1
      this.checkNorm()
    },
    initControlSet() {
      const mark = {}
      this.control.MarkLine.forEach(c => {
        mark[c.ColumnId] = c
      })
      this.controlSet = {
        ChartType: this.control.ChartType,
        IsShowHead: this.control.IsShowHead,
        Title: this.control.Title,
        YAxis: this.control.YAxis,
        XAxis: this.control.XAxis,
        MarkLine: mark,
        Legend: this.control.Legend,
        IsConfig: this.control.Selects != null && this.control.Selects.length > 0 && this.control.GroupBy != null && this.control.GroupBy.length > 0
      }
    },
    addLine() {
      this.markIndex = null
      this.mark = null
      this.visible = true
    },
    editLine(item, index) {
      this.markIndex = index
      this.mark = item
      this.visible = true
    },
    dropLine(index) {
      this.control.MarkLine.splice(index, 1)
      this.visible = true
    },
    saveMark(index, data) {
      if (index == null) {
        this.control.MarkLine.push(data)
      } else {
        this.control.MarkLine.splice(index, 1, data)
      }
    },
    resetForm() {
      const set = {
        Id: this.source.Id,
        Name: this.source.Name,
        WidthRatio: this.source.WidthRatio,
        HeightGrid: this.source.HeightGrid,
        Show: this.source.Show,
        IsShowHead: false,
        FormId: null,
        Selects: [],
        Having: null,
        ChartType: 0,
        GroupBy: null,
        YAxis: {
          MinInterval: 1,
          MaxInterval: null,
          Unit: null
        },
        XAxis: {
          Unit: null
        },
        Legend: {
          Show: true,
          Position: 1
        },
        Title: {
          Show: false,
          Align: 1
        },
        MarkLine: []
      }
      if (this.source.ControlConfig && this.source.ControlConfig.Chart) {
        const conf = this.source.ControlConfig.Chart
        if (conf.Selects) {
          conf.Selects.forEach(c => {
            c.id = this.id
            this.id = this.id + 1
          })
        }
        this.control = Object.assign(set, conf)
        this.formId = conf.FormId != null ? [conf.FormId] : null
      } else {
        this.control = set
        this.formId = null
      }
      this.max = this.chartMax[set.ChartType]
      this.checkNorm()
      this.curTab = 'data'
    },
    save() {
      const that = this
      return new Promise((resolve, reject) => {
        that.$refs['controlEdit'].validate((valid) => {
          if (valid) {
            const data = that.getData()
            if (data == null) {
              reject()
              return
            }
            resolve(data)
          } else {
            reject()
            return false
          }
        })
      })
    },
    getData() {
      const where = this.$refs.pageFilter.getValue()
      if (where.isError) {
        return null
      }
      const data = {
        Name: this.control.Name,
        WidthRatio: this.control.WidthRatio,
        HeightGrid: this.control.HeightGrid,
        Show: this.control.Show,
        ControlConfig: {
          Chart: null
        }
      }
      const config = {
        FormId: this.control.FormId,
        ChartType: this.control.ChartType,
        IsShowHead: this.control.IsShowHead,
        GroupBy: this.control.GroupBy,
        Selects: this.control.Selects.map(c => {
          const t = Object.assign({}, c)
          delete t.ColName
          return t
        }),
        Having: this.control.Having,
        YAxis: this.control.YAxis,
        XAxis: this.control.XAxis,
        Legend: this.control.Legend,
        Title: this.control.Title,
        MarkLine: this.control.MarkLine,
        Where: where.rows
      }
      data.ControlConfig.Chart = config
      return data
    }
  }
}
</script>
<style scoped>
.controlView {
    width: 100%;
    height: 600px;
    line-height: 600px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 10px;
}

.controlView .el-card {
    display: inline-block;
    line-height: normal;
}

.header {
    height: 30px;
    line-height: 30px;
    border-left: 4px solid #409eff;
    text-indent: 5px;
    font-size: 1.2em;
    margin-bottom: 5px;
}
</style>
